﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using InterfaceLiftLib.Models;
using InterfaceLiftLib.Service;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace InterfaceLiftTests
{
    [TestClass]
    public class InterfaceLiftServiceTests
    {
        private const int CameraBodyId = 1;
        private const int CameraLensId = 621;
        private const int CommentId = 651585;
        private const int CommentsWallpaperId = 3055;
        private const int FavoritesWallpapersUserId = 312;
        private const int TagId = 538;
        private const int UserInfoId = 312;
        private const int WallpaperId = 3029;
        private readonly Resolution WallpaperDownloadResolution = new Resolution(1920, 1080);

        private IInterfaceLiftService m_service;
        private ManualResetEvent m_waitEvent;

        public InterfaceLiftServiceTests()
        {
            m_service = InterfaceLiftServiceFactory.CreateNewService();
        }

        [TestInitialize]
        public void InitTest()
        {
            m_waitEvent = new ManualResetEvent(false);
        }

        [TestMethod]
        public void ShouldReturnCameraBody()
        {
            CameraBody cameraBody = null;
            m_service.GetCameraBody(CameraBodyId, (cb, ex) =>
                                                      {
                                                          cameraBody = cb;
                                                          m_waitEvent.Set();
                                                      });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(cameraBody);
            Assert.AreEqual(CameraBodyId, cameraBody.Id);
        }

        [TestMethod]
        public void ShouldReturnCameraLens()
        {
            CameraLens cameraLens = null;
            m_service.GetCameraLens(CameraLensId, (cl, ex) =>
                                                      {
                                                          cameraLens = cl;
                                                          m_waitEvent.Set();
                                                      });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(cameraLens);
            Assert.AreEqual(CameraLensId, cameraLens.Id);
        }

        [TestMethod]
        public void ShouldReturnComment()
        {
            Comment comment = null;
            m_service.GetComment(CommentId, (c, ex) =>
                                        {
                                            comment = c;
                                            m_waitEvent.Set();
                                        });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(comment);
            Assert.AreEqual(CommentId, comment.Id);
            Assert.IsFalse(String.IsNullOrEmpty(comment.CommentText));
        }

        [TestMethod]
        public void ShouldReturnComments()
        {
            IEnumerable<Comment> comments = null;
            m_service.GetComments(wallpaperId: CommentsWallpaperId, callback: (cl, ex) =>
                                                                                  {
                                                                                      comments = cl;
                                                                                      m_waitEvent.Set();
                                                                                  });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(comments);
            Assert.IsTrue(comments.Any());
        }

        [TestMethod]
        public void ShouldReturnFavoritesWallpapers()
        {
            IEnumerable<Wallpaper> favoritesWallpapers = null;
            m_service.GetFavoritesWallpapers(FavoritesWallpapersUserId, callback: (fw, ex) =>
                                                                                      {
                                                                                          favoritesWallpapers = fw;
                                                                                          m_waitEvent.Set();
                                                                                      });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(favoritesWallpapers);
            Assert.IsTrue(favoritesWallpapers.Any());
        }

        [TestMethod]
        public void ShouldReturnATag()
        {
            Tag tag = null;
            m_service.GetTag(TagId, (t, ex) =>
                                        {
                                            tag = t;
                                            m_waitEvent.Set();
                                        });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(tag);
            Assert.AreEqual(TagId, tag.Id);
        }

        [TestMethod]
        public void ShouldReturnTags()
        {
            IEnumerable<Tag> tags = null;
            m_service.GetTags("new", InterfaceLiftLib.Models.Enums.TagType.Location, (tl, ex) =>
                                                                                         {
                                                                                             tags = tl;
                                                                                             m_waitEvent.Set();
                                                                                         });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(tags);
            Assert.IsTrue(tags.Any());
        }

        [TestMethod]
        public void ShouldReturnUserInfos()
        {
            User user = null;
            m_service.GetUserInfos(UserInfoId, (u, ex) =>
                                                   {
                                                       user = u;
                                                       m_waitEvent.Set();
                                                   });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(user);
            Assert.AreEqual(UserInfoId, user.Id);
            Assert.IsFalse(String.IsNullOrEmpty(user.Username));
        }

        [TestMethod]
        public void ShouldReturnAWallpaper()
        {
            Wallpaper wallpaper = null;
            m_service.GetWallpaper(WallpaperId, (w, ex) =>
                                                    {
                                                        wallpaper = w;
                                                        m_waitEvent.Set();
                                                    });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(wallpaper);
            Assert.AreEqual(WallpaperId, wallpaper.Id);
        }

        [TestMethod]
        public void ShouldReturnWallpapers()
        {
            IEnumerable<Wallpaper> wallpapers = null;
            //without any parameters should return the ten most-recent wallpapers..
            m_service.GetWallpapers(callback: (wl, ex) =>
                                                  {
                                                      wallpapers = wl;
                                                      m_waitEvent.Set();
                                                  });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(wallpapers);
            Assert.IsTrue(wallpapers.Count() == 10);
        }

        [TestMethod]
        public void ShouldReturnWallpaperDownloadInfos()
        {
            WallpaperDownloadInfos wallpaperDownloadInfos = null;
            m_service.GetWallpaperDownloadInfos(WallpaperId, WallpaperDownloadResolution, (wd, ex) =>
                                                                                              {
                                                                                                  wallpaperDownloadInfos = wd;
                                                                                                  m_waitEvent.Set();
                                                                                              });
            m_waitEvent.WaitOne();
            Assert.IsNotNull(wallpaperDownloadInfos);
            Assert.AreEqual(WallpaperId, wallpaperDownloadInfos.WallpaperId);
            Assert.IsFalse(String.IsNullOrEmpty(wallpaperDownloadInfos.DownloadUrl));
        }
    }
}
